package com.yms.yms.utils;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 随机密码生成工具
 */
public class RandomPwd {
    private static RandomPwd instance;
    private static final String lowStr = "abcdefghijklmnopqrstuvwxyz";
    private static final String specialStr = "~!@#$%^&*()_+-=[]{}";
    private static final String numStr = "1234567890";
    private RandomPwd(){}
    public static RandomPwd getInstance() {
        // 双锁实现单例模式
        if (instance == null) {
            synchronized (RandomPwd.class) {
                if (instance == null) {
                    instance = new RandomPwd();
                }
            }
        }
        return instance;
    }

    private static char getRandomChar(String str) {
        SecureRandom random = new SecureRandom();
        return str.charAt(random.nextInt(str.length()));
    }

    private static char getLowChar() {
        return getRandomChar(lowStr);
    }

    private static char getUpperChar() {
        return Character.toUpperCase(getLowChar());
    }

    private static char getNumChar() {
        return getRandomChar(numStr);
    }

    private static char getSpecialChar() {
        return getRandomChar(specialStr);
    }

    private static char getRandomChar(int num) {
        return switch (num) {
            case 0 -> getLowChar();
            case 1 -> getUpperChar();
            case 2 -> getNumChar();
            default -> getSpecialChar();
        };
    }

    public static String getRandomPwd() {
        SecureRandom random = new SecureRandom();
        int len = random.nextInt(8,20);
        List<Character> list = new ArrayList<>(len);
        list.add(getUpperChar());
        list.add(getSpecialChar());
        list.add(getLowChar());
        list.add(getNumChar());
        for(int i=4;i<len;i++){
            list.add(getRandomChar(random.nextInt(4)));
        }
        Collections.shuffle(list);
        StringBuilder stringBuilder = new StringBuilder(list.size());
        for (Character c :
                list) {
            stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }
}
